package maa.action.admin.mentor;

import maa.action.Action;
import maa.action.ActionResult;
import maa.dao.h2.MentorDAOimpl;
import maa.dao.DAOCommand;
import maa.dao.DAOManager;
import maa.database.ConnectionPool;
import maa.entity.Gender;
import maa.entity.Mentor;
import maa.action.ActionException;
import maa.dao.DAOException;
import maa.util.FieldValidator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Date;
import java.util.UUID;

public class UpdateMentor implements Action {
    @Override
    public ActionResult execute(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        HttpSession session = req.getSession();
        ActionResult actionResult = new ActionResult();
        final Mentor mentor = new Mentor();
        mentor.setUuid(UUID.fromString(req.getParameter("uuid").substring(0, req.getParameter("uuid").length() - 1)));
        String curpass = encryptPassword(req.getParameter("curpas"));
        String email = req.getParameter("email");
        String name = req.getParameter("name");
        String surname = req.getParameter("surname");
        String gender = req.getParameter("gender").toUpperCase();
        String birthdate = req.getParameter("birthdate");
        String rang = req.getParameter("rang");
        String info = req.getParameter("info");
        String experience = req.getParameter("experience");

        if (!FieldValidator.isValidEmail(email)) {
            req.setAttribute("incorrect_email", "Email should be different");
            actionResult.setResult("mentor-update");
            return actionResult;
        }
        if (!FieldValidator.isValidName(name)) {
            req.setAttribute("incorrect_name", "Name should start with a capitol letter, consist of only letters and can be 1 to 30 symbols");
            actionResult.setResult("mentor-update");
            return actionResult;
        }
        if (!FieldValidator.isValidSurname(surname)) {
            req.setAttribute("incorrect_gender", "Surname should start with a capitol letter, consist of only letters and can be 1 to 40 symbols");
            actionResult.setResult("mentor-update");
            return actionResult;
        }
        if (!FieldValidator.isValidGender(gender)) {
            req.setAttribute("incorrect_surname", "Gender should be either 'MALE' or 'FEMALE'");
            actionResult.setResult("mentor-update");
            return actionResult;
        }
        if (!FieldValidator.isValidBirthdate(birthdate)) {
            req.setAttribute("incorrect_birthdate", "Birthdate should be submitted in the following format: yyyy-mm-dd");
            actionResult.setResult("mentor-update");
            return actionResult;
        }
        if (!FieldValidator.isValidRang(rang)) {
            req.setAttribute("incorrect_rang", "Invalid rang");
            actionResult.setResult("mentor-update");
            return actionResult;
        }
        if (!FieldValidator.isValidInfo(info)) {
            req.setAttribute("incorrect_info", "Invalid information");
            actionResult.setResult("mentor-update");
            return actionResult;
        }
        if (!FieldValidator.isValidWorkExperience(experience)) {
            req.setAttribute("incorrect_experience", "Invalid work experience");
            actionResult.setResult("mentor-update");
            return actionResult;
        }
        mentor.setPassword(curpass);
        String password = req.getParameter("password");
        String reppas = req.getParameter("reppassword");
        if (!password.isEmpty() || !reppas.isEmpty()) {
            if (!FieldValidator.isValidPassword(password)) {
                req.setAttribute("incorrect_password", "Password should be 6 to 20 symbols and consist of at least one number, one small letter, one big letter, and one of the following symbols: @#$%-_");
                actionResult.setResult("mentor-update");
                return actionResult;
            }
            if (!FieldValidator.isValidPassword(reppas)) {
                req.setAttribute("incorrect_password", "Password should be 6 to 20 symbols and consist of at least one number, one small letter, one big letter, and one of the following symbols: @#$%-_");
                actionResult.setResult("mentor-update");
                return actionResult;
            }
            if (!password.equals(reppas)) {
                req.setAttribute("unmatching_passwords", "Passwords do not match");
                actionResult.setResult("mentor-update");
                return actionResult;
            }
            String pass = encryptPassword(password);
            mentor.setPassword(pass);
        }
        mentor.setName(name);
        mentor.setEmail(email);
        mentor.setSurname(surname);
        mentor.setBirthdate(Date.valueOf(birthdate));
        mentor.setGender(Gender.valueOf(gender));
        mentor.setRang(rang);
        mentor.setInfo(info);
        mentor.setWorkExperience(Double.parseDouble(experience));
        ConnectionPool connectionPool = ConnectionPool.getInstance();
        DAOManager daoManager = new DAOManager(connectionPool.getConnection());

        DAOCommand daoCommand = new DAOCommand() {
            @Override
            public Object execute(DAOManager daoManager) throws ActionException {
                MentorDAOimpl mentorDAO = daoManager.getMentorDAO();
                try {
                    return mentorDAO.update(mentor);
                } catch (DAOException e) {
                    throw new ActionException("Exception in mentorDAO.update(mentor)");
                }
            }
        };
        Boolean flag = (Boolean) daoManager.executeAndClose(daoCommand);
        if (flag) {
            actionResult.setResult("success");
            actionResult.setRedirected(true);
            session.removeAttribute("mentor");
        } else actionResult.setResult("admin-cabinet");
        return actionResult;
    }

    private static String encryptPassword(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(password.getBytes("UTF-8"));
        return new BigInteger(1, crypt.digest()).toString(16);
    }
}
